﻿Imports WiremetModel.Entities.OEM

Public Class frmMaterialSzukanie

    Private _unitOfWork As UnitOfWork
    Private _materialDictionary As Dictionary(Of Integer, Material)

    Private Structure Filter
        Public dostawcaId As Integer
        Public gatunekId As Integer
        Public stopId As Integer
        Public wytop As String
        Public wymiar As Double?
    End Structure



    Public Sub New()
        InitializeComponent()
        _unitOfWork = New UnitOfWork()
        RefreshViewData()
        RefreshMaterialTable(_materialDictionary.Values)
    End Sub

    Private Sub frmMaterialSzukanie_Activated(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Activated
        cmb_Dostawca.SelectAll()
    End Sub

    Private Sub frmMaterialSzukanie_FormClosed(ByVal sender As Object, ByVal e As System.Windows.Forms.FormClosedEventArgs) Handles Me.FormClosed
        _unitOfWork.Dispose()
    End Sub

    Private Sub RefreshViewData()

        Dim materialRepository As New Repository(Of Material)(_unitOfWork)
        Dim dostawcaRepository As New Repository(Of Dostawca)(_unitOfWork)
        Dim gatunekRepository As New Repository(Of Gatunek)(_unitOfWork)
        Dim stopRepository As New Repository(Of [Stop])(_unitOfWork)

        _materialDictionary = materialRepository.GetAll().ToDictionary(Function(x) x.Id, Function(x) x)
        Dim dostawcaList As IEnumerable(Of Dostawca) = dostawcaRepository.GetAll().OrderBy(Function(x) x.NazwaFirmy)
        Dim gatunekList As IEnumerable(Of Gatunek) = gatunekRepository.GetAll().OrderBy(Function(x) x.NazwaAng)
        Dim stopList As IEnumerable(Of [Stop]) = stopRepository.GetAll().OrderBy(Function(x) x.Nazwa)

        InitializeFilterComboBox(cmb_Dostawca, dostawcaList.ToDictionary(Function(x) x.Id, Function(x) x.NazwaFirmy))
        InitializeFilterComboBox(cmb_Gatunek, gatunekList.ToDictionary(Function(x) x.Id, Function(x) x.NazwaAng))
        InitializeFilterComboBox(cmb_Stop, stopList.ToDictionary(Function(x) x.Id, Function(x) x.Nazwa))
        InitializeFilterComboBox(cmb_Wytop, _materialDictionary.Select(Function(x) x.Value.Wytop).Distinct().OrderBy(Function(x) x))

    End Sub

    Private Sub InitializeFilterComboBox(ByRef cmbFilter As ComboBox, ByVal data As Dictionary(Of Integer, String))

        cmbFilter.DataSource = New BindingSource(data, Nothing)
        cmbFilter.DisplayMember = "Value"
        cmbFilter.ValueMember = "Key"
        cmbFilter.AutoCompleteCustomSource.Clear()
        cmbFilter.AutoCompleteCustomSource.AddRange(data.Values.OrderBy(Function(x) x).ToArray())
        cmbFilter.SelectedIndex = -1

    End Sub

    Private Sub InitializeFilterComboBox(ByRef cmbFilter As ComboBox, ByVal data As IEnumerable(Of String))

        cmbFilter.DataSource = New BindingSource(data, Nothing)
        cmbFilter.AutoCompleteCustomSource.Clear()
        cmbFilter.AutoCompleteCustomSource.AddRange(data.OrderBy(Function(x) x).ToArray())
        cmbFilter.SelectedIndex = -1

    End Sub


    Private Sub RefreshMaterialTable(ByVal materialList As IEnumerable(Of Material))

        dgv_Material.Rows.Clear()

        For Each material As Material In materialList
            dgv_Material.Rows.Add(
                material.Id,
                If(IsNothing(material.Dostawca), String.Empty, material.Dostawca.NazwaFirmy),
                material.Gatunek.NazwaAng,
                material.Wytop)
        Next
        
    End Sub


    Private Function CreateFilter() As Filter
        Dim wymiar As Double
        Return New Filter With {
            .dostawcaId = CInt(cmb_Dostawca.SelectedValue),
            .gatunekId = CInt(cmb_Gatunek.SelectedValue),
            .wytop = cmb_Wytop.Text,
            .stopId = CInt(cmb_Stop.SelectedValue),
            .wymiar = If(Double.TryParse(tb_Wymiar.Text.Trim(), wymiar), wymiar, CType(Nothing, Double?))
        }
    End Function


    Private Function IsMaterialSatisfiedByFilter(ByVal material As Material, ByVal filter As Filter) As Boolean

        Return (filter.dostawcaId = 0 OrElse (Not IsNothing(material.Dostawca) AndAlso material.Dostawca.Id = filter.dostawcaId)) AndAlso
               (filter.gatunekId = 0 OrElse material.Gatunek.Id = filter.gatunekId) AndAlso
               (filter.wytop = String.Empty OrElse material.Wytop.StartsWith(filter.wytop, StringComparison.CurrentCultureIgnoreCase)) AndAlso
               (filter.stopId = 0 OrElse material.Gatunek.Stop.Id = filter.stopId) AndAlso
               (Not filter.wymiar.HasValue OrElse material.Wymiar = filter.wymiar.Value)
    End Function


    Private Sub RunFilter(ByVal filter As Filter)

        Dim filteredMaterials As New List(Of Material)

        For Each material As Material In _materialDictionary.Values
            If IsMaterialSatisfiedByFilter(material, filter) Then
                filteredMaterials.Add(material)
            End If
        Next

        RefreshMaterialTable(filteredMaterials)

        ComboBoxCleanupWhenNoValueSelected(cmb_Dostawca)
        ComboBoxCleanupWhenNoValueSelected(cmb_Gatunek)
        ComboBoxCleanupWhenNoValueSelected(cmb_Stop)
        ComboBoxCleanupWhenNoValueSelected(cmb_Wytop)

    End Sub


    Private Sub ComboBoxCleanupWhenNoValueSelected(ByRef comboBox As ComboBox)
        If comboBox.SelectedValue Is Nothing Then
            comboBox.ResetText()
        End If
    End Sub


    Private Sub ClearFilter()

        cmb_Dostawca.SelectedIndex = -1
        cmb_Gatunek.SelectedIndex = -1
        cmb_Stop.SelectedIndex = -1
        cmb_Wytop.SelectedIndex = -1

        cmb_Dostawca.ResetText()
        cmb_Gatunek.ResetText()
        cmb_Stop.ResetText()
        cmb_Wytop.ResetText()

    End Sub

    Private Sub EditMaterial()
        Try
            If dgv_Material.SelectedRows.Count = 0 Then
                Throw New Exception("Proszę, wybierz materiał a listy, aby kontynuować.")
            End If

            Dim materialId As Integer = CInt(dgv_Material.SelectedRows(0).Cells("MaterialId").Value)
            Dim materialForm As New frmMaterial(materialId, 0)
            materialForm.ShowDialog()
            _unitOfWork.Dispose()
            _unitOfWork = New UnitOfWork()
            Dim filter As Filter = CreateFilter()
            RefreshViewData()
            RunFilter(filter)
        Catch ex As Exception
            MessageBox.Show(ex.Message, "Warning", MessageBoxButtons.OK, MessageBoxIcon.Warning)
        End Try
    End Sub

    Private Sub btn_RunFilter_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btn_RunFilter.Click
        RunFilter(CreateFilter())
    End Sub

    Private Sub RefreshView()

        _unitOfWork.Dispose()
        _unitOfWork = New UnitOfWork()
        RefreshViewData()
        RefreshMaterialTable(_materialDictionary.Values)

    End Sub

    Private Sub btn_Refresh_Click(sender As System.Object, e As System.EventArgs) Handles ts_btn_RefreshView.Click
        RefreshView()
    End Sub

    Private Sub btn_ClearFilter_Click(sender As System.Object, e As System.EventArgs) Handles btn_ClearFilter.Click
        ClearFilter()
        RunFilter(CreateFilter())
    End Sub

    Private Sub cmdDodaj_Click(sender As System.Object, e As System.EventArgs) Handles ts_btn_AddMaterial.Click
        Try
            dgv_Material.ClearSelection()
            Dim materialForm As New frmMaterial(0, 0)
            materialForm.ShowDialog()
            Dim filter As Filter = CreateFilter()
            RefreshView()
            RunFilter(filter)
        Catch ex As Exception
            MessageBox.Show(ex.Message, "Warning", MessageBoxButtons.OK, MessageBoxIcon.Warning)
        End Try
    End Sub

    Private Sub cmdEdytuj_Click(sender As System.Object, e As System.EventArgs) Handles ts_btn_EditMaterial.Click
        EditMaterial()
    End Sub

    Private Sub dgvMaterial_CellMouseDoubleClick(sender As Object, e As DataGridViewCellMouseEventArgs) Handles dgv_Material.CellMouseDoubleClick
        EditMaterial()
    End Sub

    Private Sub btn_Dostawcy_Click(sender As Object, e As EventArgs) Handles ts_btn_Dostawcy.Click
        Try
            Dim dostawcaForm As New frmDostawca(CBool(0), 0)
            dostawcaForm.ShowDialog()
            RefreshView()
        Catch ex As Exception
            MessageBox.Show(ex.Message, "Warning", MessageBoxButtons.OK, MessageBoxIcon.Warning)
        End Try
    End Sub

    Private Sub btn_Stop_Click(sender As Object, e As EventArgs) Handles ts_btn_Stop.Click
        Try
            Dim stopForm As New frmStop()
            stopForm.ShowDialog()
            RefreshView()
        Catch ex As Exception
            MessageBox.Show(ex.Message, "Warning", MessageBoxButtons.OK, MessageBoxIcon.Warning)
        End Try
    End Sub

    Private Sub btn_Gatunek_Click(sender As Object, e As EventArgs) Handles ts_btn_Gatunek.Click
        Try
            'Dim gatunekForm As New frmGatunekMaterialuSzukanie(False, 0)
            'gatunekForm.ShowDialog()
            Dim gatunekView As New GatunekView()
            gatunekView.ShowDialog()
            RefreshView()
        Catch ex As Exception
            MessageBox.Show(ex.Message, "Warning", MessageBoxButtons.OK, MessageBoxIcon.Warning)
        End Try
    End Sub

    Private Sub filterInput_KeyDown(sender As Object, e As KeyEventArgs) Handles cmb_Dostawca.KeyDown, cmb_Gatunek.KeyDown, cmb_Wytop.KeyDown, cmb_Stop.KeyDown, tb_Wymiar.KeyDown
        If e.KeyCode = Keys.Enter Then
            RunFilter(CreateFilter())
        End If
    End Sub

End Class